package com.qf.zuul.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

@Component
@Slf4j
public class ParamFilter extends ZuulFilter {
    // 这个方法的返回值代表过滤器的类型
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;  // 代表当前过滤器是一个前置过滤器
    }

    // 该过滤器的序号，值越小越考前
    @Override
    public int filterOrder() {
        return 10;
    }

    // 该方法的返回值为true时，这个过滤器才会被执行，即run方法会被调用
    // 如果返回false，则run方法不会被调用
    @Override
    public boolean shouldFilter() {
        return true;
    }

    // 过滤器的逻辑代码写在这个run方法中
    @Override
    public Object run() throws ZuulException {
        log.info("开始执行ParamFilter，检查必传参数");
        // 在登录接口中，如果用户登录成功了，登录接口会返回一个特殊的字符串，这个字符串叫做 token （JWT）
        // 加入必传参数有：
        // (1)代表登录状态的参数 token
        // (2)代表当前请求想要访问哪个微服务的接口 apiname=provider

        // 1. 获取Request对象
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();

        // 2. 从 HttpServletRequest 对象中获取所有的参数名
        Set<String> paramNameSet = request.getParameterMap().keySet();

        // 3. 获取必传参数set集合
        HashSet<String> paramSet = new HashSet<>();
        paramSet.add("token");
        paramSet.add("apiname");

        // 4. 比较
        paramSet.removeAll(paramNameSet);
        if (paramSet.size()>0){
            log.info("必传参数缺失,{}",paramSet);
            // 有必传参数没有传
            currentContext.setSendZuulResponse(false);  //请求不要再继续发送给后面的微服务了
            HttpServletResponse response = currentContext.getResponse();

            try {
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().println("必传参数缺少了,"+paramSet);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            return null;
        }
        log.info("所有参数都传了");
        return null;
    }
}
